/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

/* eslint-disable @typescript-eslint/no-shadow */
import React, { useEffect, useState, useRef } from 'react';
import { getChildrenArea } from '@/services/YzBond';
import { Spin, Cascader, message } from 'antd';
import type { BaseOptionType } from 'antd/es/cascader';

const { SHOW_CHILD } = Cascader;
interface Options {
  label: string;
  value: string;
  id?: string;
  pid: string;
  isLeaf?: boolean;
  disabled?: boolean;
  checked?: boolean;
  children?: any;
  text?: string;
}

function arrPop(data: any, len: number) {
  return data.map((item: any) => item.slice(0, len));
}

type KbAddressSelectProps = {
  name?: string;
  label?: string;
  level?: number;
  multiple?: boolean;
  allowClear?: boolean;
  disabled?: boolean;
  value?: (string | number | (string[] | number[]))[];
  placeholder?: string;
  onChange?: (value: (string | number)[], options: any) => void;
  children?: any;
  onDropdownVisibleChange?: (status: boolean) => void;
};

const KbAddressSelect: React.FC<KbAddressSelectProps> = (props) => {
  const { level = 3, disabled, multiple, value: initValue, onChange, ...rest } = props;
  const [addressLoading, setAddressLoading] = useState<boolean>(false);
  const [options, setOptions] = useState<Options[]>([]);
  const count = useRef<number>(0);

  const mapOption = ({
    defOptions,
    key,
    data,
  }: {
    defOptions: Options[];
    key: string;
    data: Options[];
  }): Options[] => {
    return defOptions.map((item: Options) => {
      if (key == item.value) {
        return {
          ...item,
          children: data,
        };
      }
      if (item.children) {
        return {
          ...item,
          children: mapOption({
            defOptions: item.children,
            key,
            data,
          }),
        };
      }
      return item;
    });
  };

  const addressChecked = (data: string[][], level: number) =>
    data.map((item) => item.length !== level + 1).includes(true);

  const onCascaderChange = (value: any[], options: any) => {
    if (multiple && value.length > 0) {
      const checdedStatus: boolean = addressChecked(value, level);
      if (checdedStatus) {
        message.error('请选择对应等级地址');
        return;
      }
      const defValue = arrPop(value, level);
      const multipleList: any[] = [];
      defValue.forEach((item: string[]) => {
        const defItem = defValue[0];
        multipleList.push(
          item.map((item1: any, index1: any) => item1 === defItem[index1]).includes(false),
        );
      });
      if (multipleList.includes(true)) {
        message.error('对应等级下区域支持多选');
        return;
      }
    }
    if (onChange) {
      onChange(value, options);
    }
  };

  const loadData = (selectedOptions: BaseOptionType) => {
    const targetOption = selectedOptions[selectedOptions.length - 1];
    if (!targetOption.children) {
      targetOption.loading = true;
      const isLeaf = selectedOptions.length >= level;
      getChildrenArea({ id: targetOption.value }, isLeaf).then((data) => {
        targetOption.loading = false;
        targetOption.children = data;
        setOptions([...options]);
      });
    }
  };

  const getAddressList = (
    defOptions: any,
    param: string[],
    count_: number,
    addressLevel: number,
  ) => {
    let op_ = defOptions;
    const isLeaf = addressLevel == count_;
    if (count_ > param.length - 2) {
      setAddressLoading(false);
      return;
    }
    getChildrenArea({ id: param[count_] }, isLeaf).then((data) => {
      if (!data.length) return;
      // 设置初始值
      if (defOptions.length == 0) {
        op_ = data;
      }
      count.current += 1;
      op_ = mapOption({ defOptions: op_, key: param[count_], data });
      setOptions(op_);
      getAddressList(op_, param, count_ + 1, addressLevel);
    });
  };

  useEffect(() => {
    const arr = multiple ? (initValue ? initValue[0] || [] : []) : initValue || [];
    const value = ['0', ...(arr as string[])];
    setAddressLoading(true);
    if (value.length == 1) {
      getChildrenArea({ id: 0 }, level == 0).then((res) => {
        setAddressLoading(false);
        setOptions(res);
      });
      return;
    }
    getAddressList(options, value, count.current, level as number);
    return () => {
      count.current = 0;
    };
  }, [level, multiple]);

  return (
    <Spin spinning={addressLoading}>
      <Cascader
        popupClassName={`cascaderStorey__${level}`}
        value={initValue}
        disabled={disabled}
        options={options}
        changeOnSelect={!multiple}
        multiple={multiple}
        maxTagCount='responsive'
        showCheckedStrategy={SHOW_CHILD}
        onChange={onCascaderChange}
        loadData={loadData}
        {...rest}
      ></Cascader>
    </Spin>
  );
};

export default React.memo(KbAddressSelect, () => false);
